package com.woniuxy.core.service.impl;

import com.woniuxy.core.mapper.RankingMapper;
import com.woniuxy.core.mapper.RunMapper;
import com.woniuxy.core.service.RankingService;
import com.woniuxy.entity.AllUser;
import com.woniuxy.entity.DTO.RankItem;
import com.woniuxy.entity.UserEarnings;
import com.woniuxy.util.ResponseData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

@Service
public class RankingServiceImpl implements RankingService {
    private static final Logger log = LoggerFactory.getLogger(RankingServiceImpl.class);
    @Autowired
    private RankingMapper rankingMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RunMapper runMapper;
    private static final String RANK_KEY = "earnings_rank";
    private static final long MAX_TIMESTAMP = 4102444800000L; // 2100-01-01 00:00:00

    /**
     * 计算复合分数
     * @param earnings 收益金额
     * @param createTime 创建时间
     * @return 复合分数
     */
    private long calculateScore(BigDecimal earnings, Date createTime) {
        // 金额部分：转换为分为单位
        long cents = earnings.multiply(BigDecimal.valueOf(100)).longValue();

        // 时间部分：MAX_TIMESTAMP - createTime.getTime()
//        long timePart = MAX_TIMESTAMP - createTime.getTime();

        // 复合分数 = 金额部分 * 10^9 + 时间部分
        return cents * 1_000_000_000L;
//        return cents * 1_000_000_000L + timePart;

    }

    /**
     * 获取排行榜
     */
    public List<RankItem> getTopRankings(int topN){
        Set<ZSetOperations.TypedTuple<String>> tuples =
                redisTemplate.opsForZSet().reverseRangeWithScores(RANK_KEY, 0, topN - 1);
        List<RankItem> rankings = new ArrayList<>();
        int rank = 1;
        for (ZSetOperations.TypedTuple<String> tuple : tuples) {
            long score = tuple.getScore().longValue();

            // 解析金额部分
            long cents = score / 1_000_000_000L;
            BigDecimal earnings = BigDecimal.valueOf(cents).divide(BigDecimal.valueOf(100));

            // 解析时间部分
            long timePart = score % 1_000_000_000L;
//            Date createTime = new Date(MAX_TIMESTAMP - timePart);

            String username = tuple.getValue();
            rankings.add(new RankItem(
                    rank++,
                    username,
                    earnings
            ));
        }
        return rankings;
    }
    /**
     * 清除整个排行榜
     */
    public void clearRanking() {
        redisTemplate.delete(RANK_KEY);
    }
    /**
     * 更新收益表并存缓存
     * @param userId
     * @param earnings
     */
    @Override
    public void updateRanking(int userId, BigDecimal earnings) {
        BigDecimal money = rankingMapper.selEarnings(userId);
        AllUser user = runMapper.getUserById(userId);
        System.out.println(user);
        //第一次赚钱
        if (money==null){
            UserEarnings userEarnings = new UserEarnings();
            userEarnings.setUserId(userId);
            userEarnings.setUsername(user.getUsername());
            userEarnings.setEarnings(earnings);
            userEarnings.setCreateTime(new Date());
            userEarnings.setUpdateTime(new Date());
            rankingMapper.addRanking(userEarnings);
            long score = calculateScore(earnings, userEarnings.getCreateTime());
            redisTemplate.opsForZSet().add(RANK_KEY, user.getUsername(), score);
        }else {
            //后续赚钱逻辑
            BigDecimal newEarnings = earnings.add(money);
            rankingMapper.updateRanking(userId,newEarnings);
            long score = calculateScore(newEarnings, new Date());
            redisTemplate.opsForZSet().add(RANK_KEY, user.getUsername(), score);

        }

    }
}
